﻿using UnityEngine;
using System.Linq;
using ETModel;
using System.Collections.Generic;
using UnityEngine.Animations;

namespace ETModel {
    public class BarTrailEffectStateMachineRander : StateMachineBehaviour {

        public string trailGameObjectName;
        /// <summary>
        /// 是否在进入状态时就渲染并且退出时停止渲染
        /// </summary>
        public bool OnStateEnterRanding = true;

        private BarTrailEffect trail;

        protected float animationIncrement = 0.003f; // ** This sets the number of time the controller samples the animation for the weapon trails
        protected float t = 0.033f;
        private float tempT = 0;
        protected float m = 0;
        protected Vector3 lastEulerAngles = Vector3.zero;
        protected Vector3 lastPosition = Vector3.zero;
        protected Vector3 eulerAngles = Vector3.zero;
        protected Vector3 position = Vector3.zero;

        private void Awake() {
        }
        private void OnDestroy() {
            
        }

        public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
            base.OnStateEnter(animator, stateInfo, layerIndex);
            trail = animator.gameObject.GetComponentsInChildren<BarTrailEffect>().FirstOrDefault(b => b.gameObject.name == trailGameObjectName);
            if (trail == null) {
                throw new System.Exception("trailGameObjectName应该是有附加BarTrailEffect脚本的节点名");
            }
            if (OnStateEnterRanding) {
                //设置拖尾时长
                trail.SetTime(trail.DefaultParams.trailTime, trail.DefaultParams.desiredTime, trail.DefaultParams.timeTransitionSpeed);
                //开始进行拖尾
                trail.StartTrail(trail.DefaultParams.desiredTime, 0.4f);
            }
        }
        public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller) {
            base.OnStateUpdate(animator, stateInfo, layerIndex, controller);

            if (trail.trailTime <= 0) {
                return;
            }
            var t = Mathf.Clamp(Time.deltaTime, 0, 0.066f);
            trail.Itterate(Time.time);
            trail.UpdateTrail(Time.time, t);
            

            return;
            t = Mathf.Clamp(Time.deltaTime, 0, 0.066f);
            if (t > 0) {

                // ** The Animation Controller also turns the character
                // ** This is very important for smooth trails... Otherwise each frame the trail will jump to wherever the new rotation causes it to be
                // ** This could be taken further and make the animation controller move the character as well... You might want to do this if you have a character that moves very quickly
                //    
                eulerAngles = trail.gameObject.transform.eulerAngles;
                position = trail.gameObject.transform.position;
                //
                //
                while (tempT < t) {

                    //
                    // ** This loop runs slowly through the animation at very small increments
                    // ** a bit expensive, but necessary to achieve smoother than framerate weapon trails
                    //
                    tempT += animationIncrement;


                    // ** steps forward by a small increment
                    //
                    // ** Manually adjusts weights of all the animations that are applied 
                    //
                    /*
                    for (int i = 0; i < fadingStates.Count; i++) {
                        if (FadeOutAnimation(fadingStates[i], animationIncrement)) {
                            fadingStates.RemoveAt(i);
                            i--;
                        }
                    }
                    
                    if (currentState != null)
                        FadeInCurrentState(animationIncrement);
                    */
                    //
                    m = tempT / t;
                    //transform.eulerAngles = new Vector3(Mathf.LerpAngle(lastEulerAngles.x, eulerAngles.x, m), Mathf.LerpAngle(lastEulerAngles.y, eulerAngles.y, m), Mathf.LerpAngle(lastEulerAngles.z, eulerAngles.z, m));
                    //transform.position = Vector3.Lerp(lastPosition, position, m);
                    //
                    // ** Samples the animation at that moment
                    //
                    //animation.Sample();
                    //controller.GetCurrentAnimatorClipInfo(0)[0].clip.SampleAnimation(
                    
                    //
                    // ** Adds the information to the WeaponTrail
                    //

                    if (trail.trailTime > 0) {
                        trail.Itterate(Time.time - t + tempT);
                    } else {
                        trail.ClearTrail();
                    }
                }
                //
                // ** End of loop
                //
                tempT -= t;
                //
                // ** Sets the position and rotation to what they were originally
                //transform.position = position;
                //transform.eulerAngles = eulerAngles;
                lastPosition = position;
                lastEulerAngles = eulerAngles;
                //
                // ** Finally creates the meshes for the WeaponTrails (one per frame)
                //
                if (trail.trailTime > 0) {
                    trail.UpdateTrail(Time.time, t);
                }
            }
        }
        public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
            base.OnStateExit(animator, stateInfo, layerIndex);
            if (OnStateEnterRanding) {
                trail.ClearTrail();
            }
        }

    }
}
